#include "ModalSolver.h"

#include "Utility/Algebra/Config.h"
#include "Utility/Configuration/SGParameter.h"
#include "Utility/Exception/SGException.h"
#include "Utility/Logging/SGLogger.h"

#include "DataStructure/Input/Solver/Subcase.h"
#include "DBManager/IService/Input/Dynamic/IEIGRLService.h"
#include "DBManager/IService/Input/Parameter/IParameterService.h"
#include "DBManager/IService/Input/Subcase/ISubcaseService.h"
// #include "DBManager/IService/Result/Nodal/IDisplacementService.h"

#include "SGFem/Task/Kernel/MModel.h"


using SG::DataStructure::Common::Real;
using SG::DataStructure::Common::Status;
using SG::DataStructure::FEM::SOLType;
using SG::DataStructure::FEM::Project;
using SG::DataStructure::FEM::Subcase;

using namespace SG::DBManager;

void ModalSolver::Solve (const DBServiceFactorySP dbServiceFactory, const Project& project, int subcaseId)
{
    auto para = dbServiceFactory->get<ISubcaseService> ()->FindSubCase (subcaseId);
    Subcase subcase(para);

    // 模态分析参数
    // SG::Utility::SGParameter setting;
    // setting.AddInt ("SubcaseID", subcaseId);
    // setting.AddString ("FrequencySelectionMode", "LM");  //"LM"：低频优先，"SM"：高频优先

    // 获取实模态求解参数
    SG::DataStructure::FEM::EIGRLData EIGRLData;
    auto                              status = dbServiceFactory->get<IEIGRLService> ()->FindBySId (subcase.GetMethodId (), EIGRLData);
    SGInfo << "Searching for EIGRL parameters with Method ID: " << subcase.GetMethodId();
    if (Status::STATUS_Failure == status)
    {
        SGError << "can't find ModesOrder setting";
        return;
    }
    // setting.AddInt ("ModesOrder", EIGRLData.m_ND);

    Kernel::MModel         model (SG::DataStructure::FEM::SOLType::SOL_SEMODES, dbServiceFactory);
    model.Initialize ({subcaseId});
    model.CalcMatrixEquation (subcaseId);
    // Kernel::EigenValueTask calc (model, setting);

    SG::Algebra::Vec_t _OUT eigD;
    SG::Algebra::Mat_t _OUT eigV;
    model.ComputeEigenValue (EIGRLData.m_ND, _OUT eigD, _OUT eigV);

    // calc.Solve ();
    model.SetEigenVector (eigV, eigD, subcaseId);
}